Thread: Can`t cast float* to void* pointers

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    121

    Can`t cast float* to void* pointers

    Hello, I have a simple vector program which has universal void** pointer. I was able to add char*, int*, long* pointers, but when I try adding float* it gives me compile error:

    Vector.h
    Code:
    typedef struct vfunc vec_functions;
    typedef struct p Private;
    
    typedef struct v {
        Private* unacessable;
        vec_functions* callbacks;
    }Vector;
    
    Vector* newVector(int);
    typedef void (*_addElement)(Vector*, void*);
    typedef void (*_setElement)(Vector*, int, void*);
    typedef void* (*_getElement)(Vector*, int);
    
    typedef struct vfunc {
        _addElement addElement;
        _setElement setElement;
        _getElement getElement;
    } vec_functions;
    Vector.c
    Code:
    typedef struct p  {
        int capacity;
        int size;
        void** data;
    } Private;
    
    
    static void doubleAmountIfFull(Vector* v) {
        if ( v->unacessable->size >= v->unacessable->capacity ) {
            v->unacessable->capacity *= 2;
            v->unacessable->data = (void**)realloc
                    (v->unacessable->data,
                     v->unacessable->capacity);
        }
    }
    
    
    static void __addElement(Vector *v, void *d) {
        doubleAmountIfFull(v);
        v->unacessable->data[v->unacessable->size] =  d;
        v->unacessable->size++;
    }
    
    static void __setElement(Vector *v, int index, void *d) {
        if ( index < v->unacessable->capacity ||
             index > v->unacessable->capacity) {
            return;
        } else {
            v->unacessable->data[index] = d;
        }
    }
    
    static void* __getElement(Vector *v, int index) {
        if ( index < 0 ||
             index > v->unacessable->capacity ) {
            return 0x00;
        } else {
            return v->unacessable->data[index];
        }
    }
    
    
    Vector* newVector(int capacity) {
        Vector* v = (Vector*) malloc(sizeof(Vector));
        v->unacessable = (Private*) malloc(sizeof(Private));
        v->unacessable->capacity = capacity;
        v->unacessable->size = 0;
        v->unacessable->data = (void**) malloc(sizeof(void*)*capacity);
        v->callbacks = (vec_functions*) malloc(sizeof(vec_functions));
        v->callbacks->addElement = __addElement;
        v->callbacks->getElement = __getElement;
        v->callbacks->setElement = __setElement;
        return v;
    }
    And the main.c file
    Code:
    int main(void) {
        Vector* v = newVector(1000);
        v->callbacks->addElement(v, (char*)"some long string");
        v->callbacks->addElement(v, (int*) 10000);
        v->callbacks->addElement(v, (long*) 29999999);
        v->callbacks->addElement(v, (float*)3.15f);
        char* c = (char*)v->callbacks->getElement(v, 0);
        int* i  = (int*) v->callbacks->getElement(v, 1);
        long* l = (long*) v->callbacks->getElement(v, 2);
        float* f = (float*) v->callbacks->getElement(v, 3);
        printf("%s %d %d\n", c, i, l);
    }
    Compile error:
    /home/ilian/QT5/Utils-in-C/main.cpp:227: error: invalid cast from type 'float' to type 'float*'
    v->callbacks->addElement(v, (float*)(3.15f) );
    ^

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by heatblazer
    Can`t cast float* to void* pointers
    This would be most unlikely: there is an implicit conversion from float* to void*. But now let's examine the error message closely:
    Code:
    main.cpp:227: error: invalid cast from type 'float' to type 'float*'
    So nope, the problem is that you are trying to cast a float to a float*. Let's look at the code:
    Code:
    v->callbacks->addElement(v, (char*)"some long string");
    v->callbacks->addElement(v, (int*) 10000);
    v->callbacks->addElement(v, (long*) 29999999);
    v->callbacks->addElement(v, (float*)3.15f);
    There's no problem converting a string literal to char* as an array of char would be converted to a pointer to its first element anyway. The only worry is that you are storing a pointer to non-const void, which leaves open the question of whether what the pointer points to might be modified. That would be a Bad Thing since you are dealing with a string literal.

    The next three lines are problematic: you probably want to store a pointer to an object with these values, but for the first two, you end up storing a pointer that has the value of those values, i.e., you are treating 10000 and 29999999 as addresses, but they could well be invalid. The third line is what caused the error that you observed, but it is no less problematic as the other two.

    What you probably should have done is something like this:
    Code:
    char string_value[] = "some long string";
    int int_value = 10000;
    long long_value = 29999999;
    float float_value = 3.15f;
    
    v->callbacks->addElement(v, string_value);
    v->callbacks->addElement(v, &int_value);
    v->callbacks->addElement(v, &long_value);
    v->callbacks->addElement(v, &float_value);
    By the way, please note:
    Quote Originally Posted by C11 Clause 7.1.3 Paragraph 1 (part)
    — All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
    — All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
    Hence, your declaration of a typedef named _addElement and your declaration of a function named __addElement result in undefined behaviour.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    121
    Yes... Thank you. So using constants directly is forbidden....

  4. #4
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by heatblazer View Post
    Yes... Thank you. So using constants directly is forbidden....
    Not forbidden, just not what you're expecting.

    A pointer, when you get right down to it, is an address. You can pass a literal address in, but unless you somehow know the literal address that contains the data you want to access, you probably need to create a variable and take its address at runtime.

    (There are cases where you genuinely might have literal addresses to deal with. Systems with memory-mapped I/O, for example.)

    Here, you're trying to pass a pointer - an address where some data lives. In the string case, all string literals will be loaded somewhere in memory already, that's how the program can access them. That's why it works - the string already has some space allocated for it to live. In the more general case, you first have to allocate space to store the data you want (e.g. by creating a variable of that type, or by otherwise dynamically allocating the space) before there is an address to pass to your function.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 06-23-2010, 06:50 AM
  2. checking cast from void*
    By manustone in forum C++ Programming
    Replies: 12
    Last Post: 07-16-2009, 03:36 AM
  3. test void pointer before cast (instanceof)
    By jeanluca in forum C Programming
    Replies: 7
    Last Post: 05-29-2009, 04:26 AM
  4. Error: explicit type cast cannot convert 'void* to 'int*'
    By juschillin in forum C++ Programming
    Replies: 5
    Last Post: 09-04-2002, 09:19 AM
  5. type cast a pointer to void
    By rc7j in forum C++ Programming
    Replies: 1
    Last Post: 02-13-2002, 12:03 PM